/**
 * @file assignment.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2025-04-29
 *
 * @copyright Copyright (c) 2025
 *
 */

#include "assignment.h"
#include <stdarg.h>
#include <string.h>
#include <stddef.h>
void MOVE_BLOCK(const void* IN, void* OUT, size_t size) {
    if (IN == NULL || OUT == NULL || size == 0) return;
    memcpy(OUT, IN, size);
}

Bool Move(Bool en, const void* in, int size[], int out_count, ...) {
    if (!en || in == NULL || !size || out_count <= 0)
        return false;  // 如果未使能或参数异常，返回 false（即 ENO := false）

    va_list args;
    va_start(args, out_count);
		int in_size = size[0];
		if(in_size<=0) return false;
    for (int i = 0; i < out_count; ++i) {
			  int out_size = size[i+1];
        void* out = va_arg(args, void*);
			if(out_size<=0) return false;
			//1.先内存清空
        if (out != NULL ) memset(out, 0, out_size);
			  else return false;
			//2.内存拷贝
				if(in_size>out_size) memcpy(out, in, out_size);
				else  memcpy(out, in, in_size);
    }
    va_end(args);
    return true;  // 执行成功，ENO := true
}

/**
 * @brief 模拟西门子博图的 S_MOVE 指令（带使能）
 * typedef struct {
    uint8_t MaxLen;             // 固定为 254
    uint8_t ActualLen;          // 实际使用长度
    char Data[254];             // 字符内容
} S7String;
 * @param en   使能输入，为 true 时执行复制，否则不改变 dst
 * @param src  来源字符串（S7 格式）
 * @param dst  目标字符串（S7 格式）
 * @return true 始终返回 true，模拟 ENO=TRUE（也可以根据 en 决定是否返回）
 */
Bool S_MOVE(Bool en, const char *src, char *dst) {
    if (!en || src == NULL || dst == NULL)
        return true;  // ENO := true，无操作

    uint8_t maxLen = (uint8_t)dst[0];       // 目标最大长度
    uint8_t srcLen = (uint8_t)src[1];       // 实际源字符串长度

    // 限制拷贝长度不超过目标 maxLen
    uint8_t copyLen = srcLen > maxLen ? maxLen : srcLen;

    dst[1] = copyLen;
    memcpy(&dst[2], &src[2], copyLen);

    // 补0，便于调试时 printf("%s", &dst[2])
    if (copyLen < maxLen)
        dst[2 + copyLen] = '\0';
    else
        dst[2 + maxLen - 1] = '\0'; // 保底

    return true;
}
